<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  
  
  <title>redis键空间事件 | 欢迎来到guo的博客!</title>
  <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
  <meta name="description" content="键空间的功能键空间通知使得客户端可以通过订阅频道或模式， 来接收那些以某种方式改动了 Redis 数据集的事件。事件通过 Redis 的订阅与发布功能（pub&#x2F;sub）来进行分发，因此所有支持订阅与发布功能的客户端都可以在无须做任何修改的情况下， 直接使用键空间通知功能。 键空间事件的类型对于每个修改数据库的操作，键空间通知都会发送两种不同类型的事件: 12publish __keyspace@">
<meta property="og:type" content="article">
<meta property="og:title" content="redis键空间事件">
<meta property="og:url" content="http://shangguan-lingfeng.gitee.io/blog1/2021/02/02/redis%E9%94%AE%E7%A9%BA%E9%97%B4%E4%BA%8B%E4%BB%B6/index.html">
<meta property="og:site_name" content="欢迎来到guo的博客!">
<meta property="og:description" content="键空间的功能键空间通知使得客户端可以通过订阅频道或模式， 来接收那些以某种方式改动了 Redis 数据集的事件。事件通过 Redis 的订阅与发布功能（pub&#x2F;sub）来进行分发，因此所有支持订阅与发布功能的客户端都可以在无须做任何修改的情况下， 直接使用键空间通知功能。 键空间事件的类型对于每个修改数据库的操作，键空间通知都会发送两种不同类型的事件: 12publish __keyspace@">
<meta property="og:locale" content="zh_CN">
<meta property="article:published_time" content="2021-02-02T06:05:41.384Z">
<meta property="article:modified_time" content="2021-04-02T03:43:33.517Z">
<meta property="article:author" content="Jerry">
<meta property="article:tag" content="redis">
<meta name="twitter:card" content="summary">
  
    <link rel="alternate" href="/blog1/atom.xml" title="欢迎来到guo的博客!" type="application/atom+xml">
  
  
    <link rel="shortcut icon" href="/blog1/favicon.png">
  
  
    
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/typeface-source-code-pro@0.0.71/index.min.css">

  
  
<link rel="stylesheet" href="/blog1/css/style.css">

  
    
<link rel="stylesheet" href="/blog1/fancybox/jquery.fancybox.min.css">

  
<meta name="generator" content="Hexo 5.3.0"></head>

<body>
  <div id="container">
    <div id="wrap">
      <header id="header">
  <div id="banner"></div>
  <div id="header-outer" class="outer">
    <div id="header-title" class="inner">
      <h1 id="logo-wrap">
        <a href="/blog1/" id="logo">欢迎来到guo的博客!</a>
      </h1>
      
    </div>
    <div id="header-inner" class="inner">
      <nav id="main-nav">
        <a id="main-nav-toggle" class="nav-icon"></a>
        
          <a class="main-nav-link" href="/blog1/">Home</a>
        
          <a class="main-nav-link" href="/blog1/archives">Archives</a>
        
      </nav>
      <nav id="sub-nav">
        
          <a id="nav-rss-link" class="nav-icon" href="/blog1/atom.xml" title="RSS Feed"></a>
        
        <a id="nav-search-btn" class="nav-icon" title="Suche"></a>
      </nav>
      <div id="search-form-wrap">
        <form action="//google.com/search" method="get" accept-charset="UTF-8" class="search-form"><input type="search" name="q" class="search-form-input" placeholder="Suche"><button type="submit" class="search-form-submit">&#xF002;</button><input type="hidden" name="sitesearch" value="http://shangguan-lingfeng.gitee.io/blog1"></form>
      </div>
    </div>
  </div>
</header>

      <div class="outer">
        <section id="main"><article id="post-redis键空间事件" class="h-entry article article-type-post" itemprop="blogPost" itemscope itemtype="https://schema.org/BlogPosting">
  <div class="article-meta">
    <a href="/blog1/2021/02/02/redis%E9%94%AE%E7%A9%BA%E9%97%B4%E4%BA%8B%E4%BB%B6/" class="article-date">
  <time class="dt-published" datetime="2021-02-02T06:05:41.384Z" itemprop="datePublished">2021-02-02</time>
</a>
    
  </div>
  <div class="article-inner">
    
    
      <header class="article-header">
        
  
    <h1 class="p-name article-title" itemprop="headline name">
      redis键空间事件
    </h1>
  

      </header>
    
    <div class="e-content article-entry" itemprop="articleBody">
      
        <hr>
<h2 id="键空间的功能"><a href="#键空间的功能" class="headerlink" title="键空间的功能"></a>键空间的功能</h2><p>键空间通知使得客户端可以通过订阅频道或模式， 来接收那些以某种方式改动了 Redis 数据集的事件。<br>事件通过 Redis 的订阅与发布功能（pub/sub）来进行分发，<br>因此所有支持订阅与发布功能的客户端都可以在无须做任何修改的情况下， 直接使用键空间通知功能。</p>
<h2 id="键空间事件的类型"><a href="#键空间事件的类型" class="headerlink" title="键空间事件的类型"></a>键空间事件的类型</h2><p>对于每个修改数据库的操作，键空间通知都会发送两种不同类型的事件:</p>
<figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">publish __keyspace@1__:key expire</span><br><span class="line">publish __keyevent@1__:expire key</span><br></pre></td></tr></table></figure>
<p>订阅第一个频道<strong>keyspace@1</strong>:key可以接收1号数据库中所有修改键key的事件，<br>而订阅第二个频道<strong>keyevent@1</strong>:expire则可以接收1号数据库中所有执行expire命令的键。<br>以keyspace为前缀的频道被称为键空间通知，而以keyevent为前缀的频道则被称为键事件通知。</p>
<p>当我们执行最后一步expire key时：<br>键空间频道的订阅者将会接收到被执行的事件的名字。<br>键事件频道的订阅者将会接收到被执行事件的键的名字。</p>
<h2 id="键空间配置"><a href="#键空间配置" class="headerlink" title="键空间配置"></a>键空间配置</h2><p>键空间默认处于关闭状态，我们需要执行config set命令来开启或关闭键空间通知功能：<br>notify-keyspace-events选项的参数为空字符串时，功能关闭。<br>另一方面，当参数不是空字符串时，功能开启。<br>notify-keyspace-events的参数可以是以下字符的任意组合，它指定了服务器该发送哪些类型的通知：</p>
<hr>
<table>
<thead>
<tr>
<th align="left">字符</th>
<th align="left">发送的通知</th>
</tr>
</thead>
<tbody><tr>
<td align="left">K(必要)</td>
<td align="left">键空间通知，所有通知以 <strong>keyspace@<db></strong> 为前缀</td>
</tr>
<tr>
<td align="left">E(必要)</td>
<td align="left">键事件通知，所有通知以 <strong>keyevent@<db></strong> 为前缀</td>
</tr>
<tr>
<td align="left">g</td>
<td align="left">DEL 、EXPIRE 、RENAME等类型无关的通用命令的通知</td>
</tr>
<tr>
<td align="left">$</td>
<td align="left">字符串命令的通知</td>
</tr>
<tr>
<td align="left">l</td>
<td align="left">列表命令的通知</td>
</tr>
<tr>
<td align="left">s</td>
<td align="left">集合命令的通知</td>
</tr>
<tr>
<td align="left">h</td>
<td align="left">哈希命令的通知</td>
</tr>
<tr>
<td align="left">z</td>
<td align="left">有序集合命令的通知</td>
</tr>
<tr>
<td align="left">x</td>
<td align="left">过期事件：每当有过期键被删除时发送</td>
</tr>
<tr>
<td align="left">e</td>
<td align="left">驱逐(evict)事件：每当有键因为maxmemory政策而被删除时发送</td>
</tr>
<tr>
<td align="left">A</td>
<td align="left">参数g$lshzxe的别名</td>
</tr>
</tbody></table>
<p>以上字符K和E是必要条件，每次的参数必须有其一，否则通知不会被分发。</p>
<h2 id="命令产生通知"><a href="#命令产生通知" class="headerlink" title="命令产生通知"></a>命令产生通知</h2><p><strong>只有当键发生变化时，通知才会产生</strong><br>以下列表记录了不同命令所产生的不同通知：</p>
<p>DEL key [key …] 命令为每个被删除的键产生一个 del 通知。</p>
<p>RENAME key newkey 产生两个通知：为来源键（source key）产生一个 rename_from 通知，并为目标键（destination key）产生一个 rename_to 通知。</p>
<p>EXPIRE key seconds 和 EXPIREAT key timestamp 在键被正确设置过期时间时产生一个 expire 通知。当 EXPIREAT key timestamp 设置的时间已经过期，或者 EXPIRE key seconds 传入的时间为负数值时，键被删除，并产生一个 del 通知。</p>
<p>SORT key [BY pattern] [LIMIT offset count] [GET pattern [GET pattern …]] [ASC | DESC] [ALPHA] [STORE destination] 在命令带有 STORE 参数时产生一个 sortstore 事件。如果 STORE 指示的用于保存排序结果的键已经存在，那么程序还会发送一个 del 事件。</p>
<p>SET key value [EX seconds] [PX milliseconds] [NX|XX] 以及它的所有变种（SETEX key seconds value 、 SETNX key value 和 GETSET key value）都产生 set 通知。其中 SETEX key seconds value 还会产生 expire 通知。</p>
<p>MSET key value [key value …] 为每个键产生一个 set 通知。</p>
<p>SETRANGE key offset value 产生一个 setrange 通知。</p>
<p>INCR key 、 DECR key 、 INCRBY key increment 和 DECRBY key decrement 都产生 incrby 通知。</p>
<p>INCRBYFLOAT key increment 产生 incrbyfloat 通知。</p>
<p>APPEND key value 产生 append 通知。</p>
<p>LPUSH key value [value …] 和 LPUSHX key value 都产生单个 lpush 通知，即使有多个输入元素时，也是如此。</p>
<p>RPUSH key value [value …] 和 RPUSHX key value 都产生单个 rpush 通知，即使有多个输入元素时，也是如此。</p>
<p>RPOP key 产生 rpop 通知。如果被弹出的元素是列表的最后一个元素，那么还会产生一个 del 通知。</p>
<p>LPOP key 产生 lpop 通知。如果被弹出的元素是列表的最后一个元素，那么还会产生一个 del 通知。</p>
<p>LINSERT key BEFORE|AFTER pivot value 产生一个 linsert 通知。</p>
<p>LSET key index value 产生一个 lset 通知。</p>
<p>LTRIM key start stop 产生一个 ltrim 通知。如果 LTRIM key start stop 执行之后，列表键被清空，那么还会产生一个 del 通知。</p>
<p>RPOPLPUSH source destination 和 BRPOPLPUSH source destination timeout 产生一个 rpop 通知，以及一个 lpush 通知。两个命令都会保证 rpop 的通知在 lpush 的通知之前分发。如果从键弹出元素之后，被弹出的列表键被清空，那么还会产生一个 del 通知。</p>
<p>HSET hash field value 、 HSETNX hash field value 和 HMSET 都只产生一个 hset 通知。</p>
<p>HINCRBY 产生一个 hincrby 通知。</p>
<p>HINCRBYFLOAT 产生一个 hincrbyfloat 通知。</p>
<p>HDEL 产生一个 hdel 通知。如果执行 HDEL 之后，哈希键被清空，那么还会产生一个 del 通知。</p>
<p>SADD key member [member …] 产生一个 sadd 通知，即使有多个输入元素时，也是如此。</p>
<p>SREM key member [member …] 产生一个 srem 通知，如果执行 SREM key member [member …] 之后，集合键被清空，那么还会产生一个 del 通知。</p>
<p>SMOVE source destination member 为来源键（source key）产生一个 srem 通知，并为目标键（destination key）产生一个 sadd 事件。</p>
<p>SPOP key 产生一个 spop 事件。如果执行 SPOP key 之后，集合键被清空，那么还会产生一个 del 通知。</p>
<p>SINTERSTORE destination key [key …] 、 SUNIONSTORE destination key [key …] 和 SDIFFSTORE destination key [key …] 分别产生 sinterstore 、 sunionostore 和 sdiffstore 三种通知。如果用于保存结果的键已经存在，那么还会产生一个 del 通知。</p>
<p>ZINCRBY key increment member 产生一个 zincr 通知。（译注：非对称，请注意。）</p>
<p>ZADD key score member [[score member] [score member] …] 产生一个 zadd 通知，即使有多个输入元素时，也是如此。</p>
<p>ZREM key member [member …] 产生一个 zrem 通知，即使有多个输入元素时，也是如此。如果执行 ZREM key member [member …] 之后，有序集合键被清空，那么还会产生一个 del 通知。</p>
<p>ZREMRANGEBYSCORE key min max 产生一个 zrembyscore 通知。（译注：非对称，请注意。）如果用于保存结果的键已经存在，那么还会产生一个 del 通知。</p>
<p>ZREMRANGEBYRANK key start stop 产生一个 zrembyrank 通知。（译注：非对称，请注意。）如果用于保存结果的键已经存在，那么还会产生一个 del 通知。</p>
<p>ZINTERSTORE destination numkeys key [key …] [WEIGHTS weight [weight …]] [AGGREGATE SUM|MIN|MAX] 和 ZUNIONSTORE destination numkeys key [key …] [WEIGHTS weight [weight …]] [AGGREGATE SUM|MIN|MAX] 分别产生 zinterstore 和 zunionstore 两种通知。如果用于保存结果的键已经存在，那么还会产生一个 del 通知。</p>
<p>每当一个键因为过期而被删除时，产生一个 expired 通知。</p>
<p>每当一个键因为 maxmemory 政策而被删除以回收内存时，产生一个 evicted 通知。</p>
<p><strong>对通知进行验证</strong></p>
<figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">$</span><span class="bash"> redis-cli config <span class="built_in">set</span> notify-keyspace-events <span class="string">&#x27;AKE&#x27;</span></span></span><br><span class="line"><span class="meta">$</span><span class="bash"> redis-cli --csv psubscribe <span class="string">&#x27;__key*__:*&#x27;</span></span></span><br><span class="line">Reading messages... (press Ctrl-C to quit)</span><br><span class="line">&quot;psubscribe&quot;,&quot;__key*__:*&quot;,1</span><br></pre></td></tr></table></figure>
<p><strong>在其他终端里用 Redis 客户端发送命令，得到通知信息</strong></p>
<figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">&quot;pmessage&quot;,&quot;__key*__:*&quot;,&quot;__keyspace@1__:key&quot;,&quot;del&quot;</span><br><span class="line">&quot;pmessage&quot;,&quot;__key*__:*&quot;,&quot;__keyevent@1__:del&quot;,&quot;key&quot;</span><br></pre></td></tr></table></figure>
      
    </div>
    <footer class="article-footer">
      <a data-url="http://shangguan-lingfeng.gitee.io/blog1/2021/02/02/redis%E9%94%AE%E7%A9%BA%E9%97%B4%E4%BA%8B%E4%BB%B6/" data-id="cknublgbw000wv8uhfifng1c3" data-title="redis键空间事件" class="article-share-link">Teilen</a>
      
      
      
  <ul class="article-tag-list" itemprop="keywords"><li class="article-tag-list-item"><a class="article-tag-list-link" href="/blog1/tags/redis/" rel="tag">redis</a></li></ul>

    </footer>
  </div>
  
    
<nav id="article-nav">
  
    <a href="/blog1/2021/02/03/webshell/" id="article-nav-newer" class="article-nav-link-wrap">
      <strong class="article-nav-caption">Neuer</strong>
      <div class="article-nav-title">
        
          webshell
        
      </div>
    </a>
  
  
    <a href="/blog1/2021/02/01/redis%E5%8F%91%E5%B8%83%E8%80%85%E8%AE%A2%E9%98%85%E8%80%85/" id="article-nav-older" class="article-nav-link-wrap">
      <strong class="article-nav-caption">Älter</strong>
      <div class="article-nav-title">redis发布者订阅者</div>
    </a>
  
</nav>

  
</article>


</section>
        
          <aside id="sidebar">
  
    

  
    
  <div class="widget-wrap">
    <h3 class="widget-title">Tags</h3>
    <div class="widget">
      <ul class="tag-list" itemprop="keywords"><li class="tag-list-item"><a class="tag-list-link" href="/blog1/tags/CentOS/" rel="tag">CentOS</a></li><li class="tag-list-item"><a class="tag-list-link" href="/blog1/tags/Flask/" rel="tag">Flask</a></li><li class="tag-list-item"><a class="tag-list-link" href="/blog1/tags/django/" rel="tag">django</a></li><li class="tag-list-item"><a class="tag-list-link" href="/blog1/tags/docker/" rel="tag">docker</a></li><li class="tag-list-item"><a class="tag-list-link" href="/blog1/tags/gitee/" rel="tag">gitee</a></li><li class="tag-list-item"><a class="tag-list-link" href="/blog1/tags/linux/" rel="tag">linux</a></li><li class="tag-list-item"><a class="tag-list-link" href="/blog1/tags/mysql/" rel="tag">mysql</a></li><li class="tag-list-item"><a class="tag-list-link" href="/blog1/tags/python/" rel="tag">python</a></li><li class="tag-list-item"><a class="tag-list-link" href="/blog1/tags/python%E5%9F%BA%E7%A1%80%E7%9F%A5%E8%AF%86/" rel="tag">python基础知识</a></li><li class="tag-list-item"><a class="tag-list-link" href="/blog1/tags/redis/" rel="tag">redis</a></li><li class="tag-list-item"><a class="tag-list-link" href="/blog1/tags/vue/" rel="tag">vue</a></li><li class="tag-list-item"><a class="tag-list-link" href="/blog1/tags/webshell/" rel="tag">webshell</a></li><li class="tag-list-item"><a class="tag-list-link" href="/blog1/tags/%E4%BA%91%E4%B8%BB%E6%9C%BA%E5%AE%9E%E7%8E%B0%E8%A7%86%E9%A2%91%E7%9B%B4%E6%92%AD/" rel="tag">云主机实现视频直播</a></li><li class="tag-list-item"><a class="tag-list-link" href="/blog1/tags/%E5%85%B3%E4%BA%8E%E7%AC%AC%E4%B8%89%E6%96%B9/" rel="tag">关于第三方</a></li></ul>
    </div>
  </div>


  
    
  <div class="widget-wrap">
    <h3 class="widget-title">Tag Cloud</h3>
    <div class="widget tagcloud">
      <a href="/blog1/tags/CentOS/" style="font-size: 17.5px;">CentOS</a> <a href="/blog1/tags/Flask/" style="font-size: 10px;">Flask</a> <a href="/blog1/tags/django/" style="font-size: 12.5px;">django</a> <a href="/blog1/tags/docker/" style="font-size: 12.5px;">docker</a> <a href="/blog1/tags/gitee/" style="font-size: 10px;">gitee</a> <a href="/blog1/tags/linux/" style="font-size: 10px;">linux</a> <a href="/blog1/tags/mysql/" style="font-size: 12.5px;">mysql</a> <a href="/blog1/tags/python/" style="font-size: 15px;">python</a> <a href="/blog1/tags/python%E5%9F%BA%E7%A1%80%E7%9F%A5%E8%AF%86/" style="font-size: 17.5px;">python基础知识</a> <a href="/blog1/tags/redis/" style="font-size: 12.5px;">redis</a> <a href="/blog1/tags/vue/" style="font-size: 20px;">vue</a> <a href="/blog1/tags/webshell/" style="font-size: 10px;">webshell</a> <a href="/blog1/tags/%E4%BA%91%E4%B8%BB%E6%9C%BA%E5%AE%9E%E7%8E%B0%E8%A7%86%E9%A2%91%E7%9B%B4%E6%92%AD/" style="font-size: 10px;">云主机实现视频直播</a> <a href="/blog1/tags/%E5%85%B3%E4%BA%8E%E7%AC%AC%E4%B8%89%E6%96%B9/" style="font-size: 12.5px;">关于第三方</a>
    </div>
  </div>

  
    
  <div class="widget-wrap">
    <h3 class="widget-title">Archiv</h3>
    <div class="widget">
      <ul class="archive-list"><li class="archive-list-item"><a class="archive-list-link" href="/blog1/archives/2021/05/">五月 2021</a></li><li class="archive-list-item"><a class="archive-list-link" href="/blog1/archives/2021/04/">四月 2021</a></li><li class="archive-list-item"><a class="archive-list-link" href="/blog1/archives/2021/03/">三月 2021</a></li><li class="archive-list-item"><a class="archive-list-link" href="/blog1/archives/2021/02/">二月 2021</a></li><li class="archive-list-item"><a class="archive-list-link" href="/blog1/archives/2021/01/">一月 2021</a></li></ul>
    </div>
  </div>


  
    
  <div class="widget-wrap">
    <h3 class="widget-title">letzter Beitrag</h3>
    <div class="widget">
      <ul>
        
          <li>
            <a href="/blog1/2021/05/14/docker+CentOS+mysql%E5%AE%9E%E7%8E%B0%E4%B8%BB%E4%BB%8E%E5%90%8C%E6%AD%A5/">docker+CentOS+mysql实现主从同步</a>
          </li>
        
          <li>
            <a href="/blog1/2021/05/13/mysql%E5%AE%9E%E7%8E%B0%E8%AF%BB%E5%86%99%E5%88%86%E7%A6%BB(%E5%9C%A8%E4%B8%BB%E4%BB%8E%E5%90%8C%E6%AD%A5%E5%9F%BA%E7%A1%80%E4%B8%8A)/">mysql实现读写分离</a>
          </li>
        
          <li>
            <a href="/blog1/2021/05/12/%E5%9C%A8%E9%A1%B9%E7%9B%AE%E4%B8%AD%E8%87%AA%E5%8A%A8%E7%94%9F%E6%88%90%E6%8E%A5%E5%8F%A3%E6%96%87%E6%A1%A3/">在项目中自动生成接口文档</a>
          </li>
        
          <li>
            <a href="/blog1/2021/05/12/mysql%E5%AE%9E%E7%8E%B0%E4%B8%BB%E4%BB%8E%E5%90%8C%E6%AD%A5/">mysql实现主从同步</a>
          </li>
        
          <li>
            <a href="/blog1/2021/05/09/CentOS%E9%83%A8%E7%BD%B2flask%E9%A1%B9%E7%9B%AE/">nginx部署flask项目</a>
          </li>
        
      </ul>
    </div>
  </div>

  
</aside>
        
      </div>
      <footer id="footer">
  
  <div class="outer">
    <div id="footer-info" class="inner">
      
      &copy; 2021 Jerry<br>
      Powered by <a href="https://hexo.io/" target="_blank">Hexo</a>
    </div>
  </div>
</footer>

    </div>
    <nav id="mobile-nav">
  
    <a href="/blog1/" class="mobile-nav-link">Home</a>
  
    <a href="/blog1/archives" class="mobile-nav-link">Archives</a>
  
</nav>
    


<script src="/blog1/js/jquery-3.4.1.min.js"></script>



  
<script src="/blog1/fancybox/jquery.fancybox.min.js"></script>




<script src="/blog1/js/script.js"></script>





  </div>
</body>
</html>